/*
 * RenderTests.cpp
 *
 *  Created on: 09.08.2011
 *      Author: Blinov Kirill
 *      Copyright: LGPL
 */

#include <iostream>
#include <string.h>
#include <cstddef>
#include <math.h>
#include <stdlib.h>
#include <SDL/SDL.h>

#include "Visualisator/CVisualisator.h"

#include "Manager Resource/IUnit.h"
#include "Manager Resource/UnitFabric.h"

#include "Kernel/CKernel.h"

#include "Constants.h"
#include "RenderTests.h"
#include "StructSource.h"
#include "CBadPhysics.h"

volatile bool  Condition;

TThreadSafeQueue<INPUT_MESSAGE*>   InputMessageQueue;
CBadPhysics                        PhysicsEngine;

std::vector<IUnit*>  			   GameUnitsArray;

CGameCamera                MainCamera; //Default parameters are suitable


const std::string UNIT_TEMPLATE_NAME = "Ship";
const std::string UNIT_TEMPLATE_NAME2 = "Island";
const std::string WATER_TEMPLATE_NAME = "Sea";
const std::string UNIT_NAME = "FirstJet";
const std::string UNIT_NAME2 = "FirstIsland";
const float SCALE_SUBMARINE_FACTOR = 0.03f;
const float SCALE_ISLAND_FACTOR = 0.05f;
const float SCALE_WATER_FACTOR = 100.0f;
const float WATER_SHIFT_STEP = 0.01;

void
FirstRenderTest()
{
	fprintf( stdout, "--FirstRenderTest\n" );

	CVisualisator* Visualisator = CVisualisator::GetVisualisator();
	while( Condition )
	{
		std::vector<GAME_OBJECT*> GameObjectsArray;

		//Run physics calculations
		PhysicsEngine.Simulate();
		//Allocate memory for GAME_OBJECT-s
		GameObjectsArray.reserve( GameUnitsArray.size() );
		UINT Counter = 0;

		for ( std::vector<IUnit*>::const_iterator BeginIt = GameUnitsArray.begin(),
			  FinishIt = GameUnitsArray.end();
			  BeginIt != FinishIt; ++BeginIt )
		{
			IUnit* CurrentUnit = *BeginIt.base();
			GAME_OBJECT* TmpGameObject = CurrentUnit->GetVisualInfo();

			GameObjectsArray.push_back( TmpGameObject );

			Counter++;
		}
		CResourceWarehouse* ResourceWarehouse = ResourceOwner::GetResourceWarehouse();

		boost::this_thread::sleep( boost::posix_time::milliseconds( RENDER_DEFAULT_WAIT_TIME ) );

		//UINT CurrentUnitToControl = GuiManager.GetControlParam( "CCheckBox1", PARAM_CHECKED ) ? SecondShipID : FirstShipID;
	}

	Visualisator->StopVisualisation();
}

int
Mmain( )
{
	memset( ShipsForces, 0, sizeof(ShipsForces) );

	CKernel* Kernel = CKernel::GetInstance();

	SCREEN_DIMENSION NewWindow;
	NewWindow.width = WINDOW_WIDTH;
	NewWindow.height = WINDOW_HEIGHT;
	NewWindow.multisampleBufferCount = 4;
	NewWindow.sdlFlags = SDL_HWSURFACE | SDL_OPENGL;

	Kernel->InitEngine( "./ShablonsGUI/TestShablon.txt",
						"./ShablonsGUI/MapGUI.txt",
						"shaders/effects.cfg",
						"content/units/units_simple.txt",
						"content/worlds/ships_world.wrld",
						NewWindow );

	//--------------Create Units------------------------------------
	IUnit *Ship1, *Ship2, *Island, *Water = NULL;
	UNIT_INITIAL_PHYSIC_PARAMS PhysicParams;
	glm::vec3 Gabarits[2];

	PhysicParams.initialPosition = glm::vec3( -5.0, 5.0, 1.7 );
	UnitFabric::CreateUnit( PhysicParams, UNIT_TEMPLATE_NAME2, UNIT_NAME2, &Island );
	assert( Island );
	GameUnitsArray.push_back( Island );
	Gabarits[0] = Island->GetVisualInfo()->dimensionCorner;
	Gabarits[1] = Island->GetVisualInfo()->dimensionCorner * glm::vec3( -1.0 );
	PhysicsEngine.AddRigidObject( 0.0, Island->GetVisualInfo()->orientation, Island->GetVisualInfo()->translation,
			                      Gabarits, glm::vec3( 0.0, 0.0, 0.0 ) );

	PhysicParams.initialPosition = glm::vec3( -15.0, 19.0, 4.0 );
	UnitFabric::CreateUnit( PhysicParams, UNIT_TEMPLATE_NAME, UNIT_NAME, &Ship1 );
	assert( Ship1 );
	GameUnitsArray.push_back( Ship1 );
	Gabarits[0] = Ship1->GetVisualInfo()->dimensionCorner;
	Gabarits[1] = Ship1->GetVisualInfo()->dimensionCorner * glm::vec3( -1.0 );
	//PhysicObjectFabric::CreatePhysicsObject();
	FirstShipID = PhysicsEngine.AddRigidObject( 1.0, Ship1->GetVisualInfo()->orientation,
			                                    Ship1->GetVisualInfo()->translation,
			                                    Gabarits, glm::vec3( 0.0, 0.0, 0.0 ) );

	PhysicParams.initialPosition = glm::vec3( 2.0, -5.0, 4.0 );
	UnitFabric::CreateUnit( PhysicParams, UNIT_TEMPLATE_NAME, UNIT_NAME, &Ship2 );
	assert( Ship2 );
	GameUnitsArray.push_back( Ship2 );
	Gabarits[0] = Ship2->GetVisualInfo()->dimensionCorner;
	Gabarits[1] = Ship2->GetVisualInfo()->dimensionCorner * glm::vec3( -1.0 );
	SecondShipID = PhysicsEngine.AddRigidObject( 1.0, Ship2->GetVisualInfo()->orientation,
			                                     Ship2->GetVisualInfo()->translation,
			                                     Gabarits, glm::vec3( 0.0, 0.0, 0.0 ) );

	PhysicParams.initialPosition = glm::vec3( 0.0, 0.0, 0.9 );
	UnitFabric::CreateUnit( PhysicParams, WATER_TEMPLATE_NAME, UNIT_NAME2, &Water );
	GameUnitsArray.push_back( Water );

	//Create water level plane
	PhysicsEngine.AddPlane( glm::vec3( 0.0f, 0.0f, 0.1f), 0.0f );

	return 0;
}
